//
//  ViewController.m
//  27-Block
//
//  Created by dllo on 16/8/19.
//  Copyright © 2016年 dllo. All rights reserved.
//

#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()
//写在属性中
@property (nonatomic,copy) void (^syblock)();
//block写在方法中
- (void)handleData:(void(^)(void))handleData;

@property (retain, nonatomic) IBOutlet UILabel *textLabel;


@end

@implementation ViewController

- (IBAction)push:(id)sender {
    SecondViewController *svc = [[SecondViewController alloc] init];
    SecondViewController *__block weakSecondVC = svc;
    [self.navigationController pushViewController:svc animated:YES];
//    值传递，需要实现block
   
//    告诉block，该指针弱引用
    svc.passTitle = ^(NSString *title) {
//        block会对其内部的所有对象进行强引用
        self.textLabel.text = title;
        weakSecondVC.view.backgroundColor = [UIColor yellowColor];
    };
    [svc release];
}


- (void)handleData:(void (^)(void))handleData
{
    [[NSURLSession sharedSession] dataTaskWithRequest:[NSURLRequest new]completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        handleData();
    }];
//    handleData();
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    block是什么？消息传递机制之一
//    与函数相似，有固定功能的代码段
//    基本语法
//    int a;
//    1.block声明，
//    类型void (^）(void);，block是变量名 返回值类型（^block名）（参数列表）
//    void (^block)(void);
//    2.block赋值，block变量 = ^(参数列表) {有固定的代码段 }；
//    block = ^(void) {
    
//    };
    
//    3.Block的形式
//    有参有返回
//    NSString *(^block4)(NSString *text) = ^(NSString *string)
//    {
//        return [string stringByAppendingString:@"有返回值"];
//    };
//    NSLog(@"block4----%@",block4(@"有参"));
////    无参无返回
//    __block int a = 0;
//    void(^block1)(void) = ^(void)
//    {
//        a++;
//    };
//    block1();
////    有参无返回
//    void(^block2)(int age,NSString *string) = ^(int age,NSString *string)
//    {
//        NSLog(@"有参无返回");
//    };
//    block2(20,@"小明");
////    无参有返回
//    NSString *(^block3)(void) = ^(void)
//    {
//        return @"无参有返回值";
//    };
//    NSLog(@"block3---%@",block3());
//    
////    系统提供了代码段可以直接使用，inline
////    最间写法
//    void(^block5)() = ^{
//        
//    };
//    block调用
    
    
    
    // 3. block的四种形式
    // <1> 无参无返回值
    void (^myBlock)();
    myBlock = ^(void){
        self.view.backgroundColor = [UIColor redColor];
    };
    // 最终简略版可以是
    void (^block1)() = ^{};
    // <2> 无参有返回值
    NSString* (^yourBlock)();
    yourBlock = ^(void){
        
        return @"";
    };
    // <3> 有参无返回值
    void(^printNumber)(int number) = ^(int number) {
        
        NSLog(@"%d", number);
    };
    
    // <4> 有参有返回值
    int (^sum)(int a, int b);
    sum = ^(int a, int b){
        return a + b;
    };
    // 系统提供的block代码块可以直接使用 打inline索引
    //    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
    //        <#statements#>
    //    };
    
    
    // 4. block的调用
    myBlock();
//    5系统中的block
//    1.模态
//    [self presentViewController:[UIViewController new] animated:YES completion:<#^(void)completion#>];
//    2.GCD同步和异步dispatch_block_t
//    dispatch_sync(dispatch_get_main_queue(), ^{
    
//    });
//    3网络请求
//    [[NSURLSession sharedSession] dataTaskWithRequest:[NSURLRequest new] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    
//    }];
    
//    6.带参数的block写在属性和方法上
//    属性block修饰符，使用copy
//    带block的方法的调用
    self.syblock = block1;
    _syblock();
    [self handleData:^{
        
    }];
//    7block的类型修饰符
//    __block __weak __strong
    
    //1》Block在arc和mrc下有区别
//    arc和mrc下否可以
//    可以在block内部修改外部变量
//    arc下不能避免循环引用问题
//    mrc下可以
    int __block a = 0;
    __block int b = 0;
    void (^blockTest)() = ^{
        a = 100;
    };
    
//    2》 __weak弱引用 修饰block外的变量
//    只能在arc下使用，避免block的循环引用
    
//    3》 __strong 强引用
    
    
    
    
    
//    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
//        <#statements#>
//    };
    
    
    
    
    
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
